package com.fh.shop.api.order.biz;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.fh.shop.api.cart.vo.CartItemVo;
import com.fh.shop.api.cart.vo.CartVo;
import com.fh.shop.api.common.*;
import com.fh.shop.api.exception.StockException;
import com.fh.shop.api.order.mapper.IOrderDetailMapper;
import com.fh.shop.api.order.mapper.IOrderMapper;
import com.fh.shop.api.order.po.Order;
import com.fh.shop.api.order.po.OrderDetail;
import com.fh.shop.api.order.vo.OrderVo;
import com.fh.shop.api.product.mapper.IProductMapper;
import com.fh.shop.api.product.po.Product;
import com.fh.shop.api.recipient.biz.IRecipientService;
import com.fh.shop.api.recipient.po.Recipient;
import com.fh.shop.api.util.KeyUtil;
import com.fh.shop.api.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service("orderService")
@Transactional(rollbackFor = Exception.class)
public class IOrderServiceImpl implements IOrderService {
    @Autowired
    private IOrderMapper orderMapper;
    @Autowired
    private IOrderDetailMapper orderDetailMapper;
    @Resource(name = "recipientService")
    private IRecipientService recipientService;
    @Autowired
    private IProductMapper productMapper;

    @Override
    public  ServerResponse submitOrder(Long recipientId, Integer payType, Long memberId) {
        // 为了让大家看到更明显的高并发的效果
//        try {
//            Thread.sleep(50);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        // 非空验证
        if (recipientId == null || payType == null) {
            return ServerResponse.error(ResponseEnum.ORDER_INFO_IS_NULL);
        }
        // 验证支付类型
        boolean validateType = PayTypeEnum.isValidateType(payType);
        if (!validateType) {
            return ServerResponse.error(ResponseEnum.ORDER_PAY_TYPE_IS_ERROR);
        }
        // 验证收件人
        ServerResponse recipientResponse = recipientService.findRecipient(recipientId, memberId);
        int code = recipientResponse.getCode();
        if (code != ResponseEnum.SUCCESS.getCode()) {
            return recipientResponse;
        }
        // 获取收件人
        Recipient recipient = (Recipient) recipientResponse.getData();
        // 验证购物车是否为空
        String cartKey = KeyUtil.buildCartKey(memberId);
        String cartJson = RedisUtil.hget(cartKey, SystemConstant.CART_CONTENT);
        if (cartJson == null) {
            return ServerResponse.error(ResponseEnum.CART_IS_NULL);
        }
        // 获取购物车
        CartVo cartVo = JSON.parseObject(cartJson, CartVo.class);
        // 再次判断下商品的库存是否足够
        // 购物车：华为p50(5)  苹果13(2)
        // 商品:华为p50(4)  苹果13(3)
        // select * from t_product where id in(1, 2, 5)
        // 购物车中的商品
        List<CartItemVo> cartItemVoList = cartVo.getCartItemVoList();
        List<Long> idList = cartItemVoList.stream().map(x -> x.getProductId()).collect(Collectors.toList());
        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.select("id", "productName", "stock");
        productQueryWrapper.in("id", idList);
        // 查询出来的商品
        List<Product> productList = productMapper.selectList(productQueryWrapper);
        // 如果购物车中的商品，有一个库存不足，那么整个购物车中的商品就都不购买。
        // 需要把库存不足的商品 给 提示出来
        List<String> productNameList = new ArrayList<>();
        // 循环对比
        cartItemVoList.forEach(x -> {
            // 从商品列表中，找到和购物车中商品对应的
            Product product = productList.stream().filter(y -> y.getId().longValue() == x.getProductId().longValue())
                                         .findFirst()
                                         .get();
            // 如果库存量<购买的数量
            // 张三 p20[1]; 李四 p20[1]
            // p20 [1]
            if (product.getStock().longValue() < x.getCount().intValue()) {
                productNameList.add(x.getProductName());
            }
        });
        // 如果productNameList不为空,证明有商品库存不足了
        if (productNameList.size() > 0) {
//            return ServerResponse.error(4288, "库存不足:"+ StringUtils.join(productNameList, ","));
            return ServerResponse.error(ResponseEnum.ORDER_STOCK_IS_ERROR, StringUtils.join(productNameList, ","));
        }
        // 下订单的时候，减库存 [循环执行]
        // update t_product set stock=stock-#{count} where id=#{productId}
        // update t_product set stock=stock-#{count} where id=#{productId} and stock>=#{count}
        // 张三 p20[1]; 李四 p20[1]
        // p20 [1]
        cartItemVoList.forEach(x -> {
            int rows = productMapper.updateStock(x.getCount(), x.getProductId());
            if (rows == 0) {
                productNameList.add(x.getProductName());
            }
        });
        if (productNameList.size() > 0) {
//            return ServerResponse.error(4288, "库存不足:"+ StringUtils.join(productNameList, ","));
            // 回滚之前的操作
            // 提示相关的信息
            throw new StockException(ServerResponse.error(ResponseEnum.ORDER_STOCK_IS_ERROR, StringUtils.join(productNameList, ",")));
        }
        // 插入订单表
        Order order = new Order();
        // 通过 雪花算法 生成唯一标识【订单id】
        String orderId = IdWorker.getIdStr();
        order.setId(orderId);
        order.setPayType(payType);
        order.setTotalPrice(new BigDecimal(cartVo.getTotalPrice()));
        order.setTotalCount(cartVo.getTotalCount().intValue());
        order.setMemberId(memberId);
        order.setRecipientId(recipientId);
        order.setRecipientName(recipient.getRecipientName());
        order.setAddr(recipient.getAddr());
        order.setPhone(recipient.getPhone());
        order.setCreateTime(new Date());
        order.setStatus(OrderStatusEnum.WAIT_PAY.getStatus());
        orderMapper.insert(order);
        // 插入订单明细表
        if (cartItemVoList.size() > 0) {
            List<OrderDetail> orderDetailList = cartItemVoList.stream().map(x -> {
                OrderDetail orderDetail = new OrderDetail();
                orderDetail.setOrderId(orderId);
                orderDetail.setProductId(x.getProductId());
                orderDetail.setProductName(x.getProductName());
                orderDetail.setImage(x.getImage());
                orderDetail.setPrice(new BigDecimal(x.getPrice()));
                orderDetail.setSubTotal(new BigDecimal(x.getSubTotal()));
                orderDetail.setCount(x.getCount().intValue());
                return orderDetail;
            }).collect(Collectors.toList());
            // 批量插入
            orderDetailMapper.addBatch(orderDetailList);
        }
        // 删除购物车 [已经将购物车中的信息，插入到订单表，订单明细表]
        RedisUtil.delete(cartKey);
        return ServerResponse.success(orderId);
    }

    @Override
    public ServerResponse findOrderList(Long memberId) {
        // 获取会员对应的订单列表
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.eq("memberId", memberId);
        List<Order> orderList = orderMapper.selectList(orderQueryWrapper);
        List<OrderVo> orderVoList = orderList.stream().map(x -> {
            OrderVo orderVo = new OrderVo();
            orderVo.setId(x.getId());
            orderVo.setPayTime(x.getPayTime());
            orderVo.setAddr(x.getAddr());
            orderVo.setPhone(x.getPhone());
            orderVo.setStatus(x.getStatus());
            orderVo.setCreateTime(x.getCreateTime());
            orderVo.setRecipientName(x.getRecipientName());
            orderVo.setTotalCount(x.getTotalCount());
            orderVo.setTotalPrice(x.getTotalPrice().toString());
            return orderVo;
        }).collect(Collectors.toList());
        return ServerResponse.success(orderVoList);
    }
}
